/*
 * shared_buffer_mgr.hpp
 *
 *  Created on: 2018年3月21日
 *      Author: Dylan.Gao
 */

#ifndef _DM_OS_SHARED_BUFFER_MGR_HPP_
#define _DM_OS_SHARED_BUFFER_MGR_HPP_

#include <dm/os/types.hpp>
#include <dm/os/shared_memory.hpp>
#include <dm/os/shared_buf.hpp>
#include <dm/fixdstring.hpp>
#include <dm/magic.hpp>
#include <dm/scoped_ptr.hpp>
#include <dm/ptrvector.hpp>
#include <dm/os/log/logger.hpp>
#include <typeinfo>
#include <cstdio>
#include <vector>

namespace dm{
namespace os{

/**
 * 共享缓冲区管理器类
 * 实现了基于共享内存的动态数组的管理
 * @tparam TRecord 记录类型
 * @tparam TStoreRecord 存储记录类型
 * @tparam TId id类型
 * @tparam SizeOfMasks 单个缓冲区掩码大小
 * @tparam TSize 大小类型
 * @tparam TIndex 索引类型
 */
template<typename TRecord,typename TId=dm::int64,typename TMask=dm::uint8,int SizeOfMasks=8,int SizeOfName=64,typename TSize=dm::uint32,typename TIndex=dm::int32>
class TCSharedBufferMgr{
public:
	// 魔数类型
	typedef dm::CMagic::magic_t magic_t;

	// 缓冲区类型
    typedef dm::os::TSSharedBuf<TRecord,TMask,SizeOfMasks> buffer_t;

	/**
	 * 缓冲区名字类型
	 */
	typedef dm::CFixdString<SizeOfName> name_t;

	typedef boost::interprocess::mapped_region mapped_region_t;

	/**
	 * 缓冲区信息类型
	 * 记录了缓冲区的全局信息
	 */
	struct SBufferInfo{
		upgradable_mutex_t mutex;	//!< 全局锁。对缓冲区的访问必须加锁。修改时，必须升级锁
		magic_t magic;	//!< 全局魔数。代表了缓冲区发生了变化
		TSize bufCount;	//!< 缓冲区个数
		TSize recordCount;	//!< 记录个数
	};

	/**
	 * 加载器类
	 */
	class CLoader{
	public:
		virtual ~CLoader(){}

		/**
		 * 增加一个已经加载的记录。执行多次，用于选择未加载的记录
		 * @param r
		 * @return
		 */
        virtual bool addALoaded( TRecord& record )=0;

		/**
		 * 过滤已经加载的记录
		 * @param r
		 * @return
		 */
		virtual bool filterLoaded()=0;

		/**
		 * 移动到下一个记录
		 * @return
		 * @attention 第一次获取记录前应该调用
		 */
		virtual bool next()=0;

		/**
		 * 初始化记录
		 * @param index 本次初始化序号
		 * @param r
		 * @return
		 */
        virtual bool loadRecord( TRecord& record )=0;

        virtual bool reloadRecord( TRecord& record ){
        	log().debug("TCSharedBufferMgr.CLoader",this,__FUNCTION__, "默认返回失败");
        	return false;
        }
	};

	/**
	 * 记录卸载器类
	 */
	class CUnloader{
	public:
		virtual ~CUnloader(){}

		/**
		 * 默认卸载，无操作
		 * @param r
		 * @return
		 */
        virtual bool unloadRecord( TRecord& record ){
        	log().debug("TCSharedBufferMgr.CUnloader",this,__FUNCTION__, "默认返回成功");
			return true;
		}
	};

	/**
	 * 记录查找类
	 */
	class CFinder{
	public:
		virtual ~CFinder(){}

		/**
		 * 用id来比较记录
		 * @param record
		 * @param id
		 * @return 是否id相同
		 */
        virtual bool compareId( TRecord& record,const TId& id ){
        	log().debug("TCSharedBufferMgr.CFinder",this,__FUNCTION__, "默认返回失败");
			return false;	// 默认失败
		}

		/**
		 * 用名字来比较记录
		 * @param record
		 * @param name
		 * @return
		 */
        virtual bool compareName( TRecord& record,const char* name ){
        	log().debug("TCSharedBufferMgr.CFinder",this,__FUNCTION__, "默认返回失败");
			return false;	// 默认失败
		}

		/**
		 * 用其他信息来比较记录
		 * @param record
		 * @param key
		 * @return
		 */
        virtual bool compareAny( TRecord& record,void* key ){
        	log().debug("TCSharedBufferMgr.CFinder",this,__FUNCTION__, "默认返回失败");
			return false;
		}
	};

	class CIdFinder:public CFinder{
	public:
        bool compareId( TRecord& record,const TId& id ){
            return record.id==id;
		}
	};

	class CNameFinder:public CFinder{
	public:
        bool compareName( TRecord& record,const char* name ){
            return record.name==name;
		}
	};

	class CKeyFinder:public CFinder{
	public:
        bool compareAny( TRecord& record,void* key ){
            return memcmp(&record,key,sizeof(TRecord))==0;
		}
	};

	/**
	 * 记录读取器
	 */
	class CReader{
	public:
		virtual ~CReader(){}

		/**
		 * 读取记录
		 * @param idx 记录索引值
		 * @param record 记录
		 * @param value 值存放区
		 * @return
		 */
        virtual bool readRecord( TRecord& record,void* pValue )=0;
	};

    template<typename TValue>
    class TCReader:public CReader{
    public:
        virtual ~TCReader(){}

        bool readRecord( TRecord& record,void* pValue ){
            TValue* p = reinterpret_cast<TValue*>(pValue);
            if( !p )
                return false;
            return readRecord(record,*p);
        }

    protected:
        virtual bool readRecord( TRecord& record,TValue& value ) = 0;
    };

    class CNormalReader:public TCReader<TRecord>{
    protected:
        bool readRecord( TRecord& record,TRecord& value ){
            value = record;
            return true;
        }
    };

	/**
	 * 记录写入器
	 */
	class CWriter{
	public:
		virtual ~CWriter(){}

        virtual bool writeRecord( void* pValue,TRecord& record )=0;
	};

    template<typename TValue>
    class TCWriter:public CWriter{
    public:
        virtual ~TCWriter(){}

        bool writeRecord( void* pValue,TRecord& record ){
            TValue* p = reinterpret_cast<TValue*>(pValue);
            if( !p )
                return false;
            return writeRecord(*p,record);
        }

    protected:
        virtual bool writeRecord( TValue& value,TRecord& record ) = 0;
    };

	/**
	 * 记录更新器
	 */
	class CUpdater{
	public:
		virtual ~CUpdater(){}

		/**
		 * 使用新的值更新记录
		 * @param idx
		 * @param oldRecord
		 * @param newRecord
		 * @return 数据是否更新
		 */
        virtual bool updateRecord( void* pValue,TRecord& record )=0;
	};

    template<typename TValue>
    class TCUpdater:public CUpdater{
    public:
        virtual ~TCUpdater(){}

        bool updateRecord( void* pValue,TRecord& record ){
            TValue* p = reinterpret_cast<TValue*>(pValue);
            if( !p )
                return false;
            return updateRecord(*p,record);
        }

    protected:
        virtual bool updateRecord( TValue& value,TRecord& record ) = 0;
    };

	/**
	 * 缓冲区记录位置
	 */
	class CPos{
	public:
		CPos(TIndex bufferIndex=-1,TIndex bufferOffset=-1,volatile magic_t* magic=nullptr,volatile buffer_t* buffer=nullptr ):
			m_bufferIndex(bufferIndex),m_bufferOffset(bufferOffset),m_bufferMagic(magic),m_buffer(buffer){
		}

		CPos(TIndex bufferIndex,TIndex bufferOffset,volatile SBufferInfo* info,std::vector<volatile buffer_t*>& buffers ):
			m_bufferIndex(bufferIndex),m_bufferOffset(bufferOffset),m_bufferMagic(&(info->magic)),m_buffer(buffers[bufferIndex]){
		}

		CPos( const CPos& pos ):m_bufferIndex(pos.m_bufferIndex),m_bufferOffset(pos.m_bufferOffset),m_bufferMagic(pos.m_bufferMagic),m_buffer(pos.m_buffer){
		}

		CPos& operator=( const CPos& pos ){
			m_bufferIndex = pos.m_bufferIndex;
			m_bufferOffset = pos.m_bufferOffset;
			m_bufferMagic = pos.m_bufferMagic;
			m_buffer = pos.m_buffer;

			return *this;
		}

		inline bool isValid()const{
			return m_bufferMagic.ifValid() && m_bufferIndex>=0 && m_bufferOffset>=0;
		}

		inline operator bool()const{
			return isValid();
		}

		inline bool operator!()const{
			return !isValid();
		}

		/**
		 * 获取缓冲区索引号
		 * @return
		 */
		inline const TIndex& getBufferIndex()const{
			return m_bufferIndex;
		}

		/**
		 * 获取缓冲区内部记录偏移
		 * @return
		 */
		inline const TIndex& getBufferOffset()const{
			return m_bufferOffset;
		}

        inline void set( TIndex bufferIdx,TIndex bufferOffset,volatile SBufferInfo* info,std::vector<volatile buffer_t*>& buffers ){
            m_bufferIndex = bufferIdx;
            m_bufferOffset = bufferOffset;
            m_bufferMagic = &(info->magic);
            m_buffer = buffers[bufferIdx];
        }

	private:
		TIndex m_bufferIndex;		// 缓冲区索引号
		TIndex m_bufferOffset;		// 记录在缓冲区中的偏移
		dm::CMagic m_bufferMagic;	// 缓冲区魔数
		volatile buffer_t* m_buffer;			// 缓冲区
	};


public:
	/**
	 * 构造函数
	 * @param name
	 */
	TCSharedBufferMgr( const char* name ):m_name(name){
		log().debug(m_name.c_str(), this, __FUNCTION__, "创建对象");
		m_infoMappedRegion = getSharedMemory<SBufferInfo>(m_name.c_str(),CUnrestrictedPermissions(),&m_info);

		SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);
		boost::interprocess::upgradable_lock<upgradable_mutex_t> ulock(pInfo->mutex);
		try{
			m_magic = new CMagic(&(m_info->magic));
			if( m_magic->ifValid() ){	// 加载信息即可
				log().debug(m_name.c_str(), this, __FUNCTION__, "对象存在,直接加载缓冲区%d个",pInfo->bufCount);
				for( TIndex i=0;i<pInfo->bufCount;++i ){
					volatile buffer_t* vbuf;
					mapped_region_t* region = loadBuffer(i,vbuf);
					if( region ){
						m_buffers.push_back(vbuf);
						m_buffersMappedRegion.append(region);
					}else{
						log().error(m_name.c_str(), this, __FUNCTION__, "加载缓冲区%d失败",i);
						return;
					}
				}
			}else{	// 信息未加载，需要加载
                log().debug(m_name.c_str(),this,__FUNCTION__,"对象初始化");
				boost::interprocess::scoped_lock<upgradable_mutex_t> lock(boost::move(ulock));
                pInfo->bufCount = 0;
                pInfo->recordCount = 0;
                m_magic->refresh();
			}
		}catch(...){
			log().error(m_name.c_str(),this,__FUNCTION__,"对象构造失败");
		}
	}

    virtual ~TCSharedBufferMgr(){
    	log().debug(m_name.c_str(), this, __FUNCTION__, "析构对象");
    }

    /**
     * 获取有效记录数
     * @return
     */
    TSize count(){
    	SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);

    	boost::interprocess::sharable_lock<upgradable_mutex_t> sharebleLock(pInfo->mutex);
		updateBuffers();

		TSize c = 0;
		for( TIndex i=0;i<m_info->bufCount;++i ){
			buffer_t* pBuffer = const_cast<buffer_t*>(m_buffers[i]);
			boost::interprocess::sharable_lock<upgradable_mutex_t> bufLock(pBuffer->mutex);
			c += pBuffer->count;
		}

		return c;
    }

    bool first( void* pValue,CReader& reader ){
    	SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);

    	boost::interprocess::sharable_lock<upgradable_mutex_t> sharebleLock(pInfo->mutex);
		updateBuffers();

		for( int idx=0;idx<pInfo->bufCount;++idx ){
			buffer_t* pBuffer = const_cast<buffer_t*>(m_buffers[idx]);
			boost::interprocess::sharable_lock<upgradable_mutex_t> bufLock(pBuffer->mutex);
			int offset = pBuffer->firstMasked();
			if( offset>=0 )
				return reader.readRecord(pBuffer->data[offset],pValue);
		}

		return false;
    }
    /**
     * 获取第一条记录
     * @param pos
     * @param record
     * @param reader
     * @return
     */
    inline bool first( CPos& pos,void* pValue=nullptr,CReader* reader=nullptr ){
    	return pos = first(pValue,reader);
    }

    CPos first(void* pValue=nullptr,CReader* reader=nullptr ){
    	SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);

    	boost::interprocess::sharable_lock<upgradable_mutex_t> sharebleLock(pInfo->mutex);
		updateBuffers();

		for( int idx=0;idx<pInfo->bufCount;++idx ){
			buffer_t* pBuffer = const_cast<buffer_t*>(m_buffers[idx]);
			boost::interprocess::sharable_lock<upgradable_mutex_t> bufLock(pBuffer->mutex);
			int offset = pBuffer->firstMasked();
			if( offset>=0 ){
                if( reader && pValue ){
                    if(! reader->readRecord(pBuffer->data[offset],pValue) ){
                    	log().warnning(m_name.c_str(),this,__FUNCTION__,"read fail[idx:%d,offset:%d]",idx,offset);
                    	return CPos();
                    }
                }

                return CPos(idx,offset,m_info,m_buffers);
			}
		}

		return CPos();
    }

    CPos last( void* pValue=nullptr,CReader* reader=nullptr ){
    	SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);

    	boost::interprocess::sharable_lock<upgradable_mutex_t> sharebleLock(pInfo->mutex);
		updateBuffers();

		for( int idx=pInfo->bufCount-1;idx>=0;--idx ){
			buffer_t* pBuffer = const_cast<buffer_t*>(m_buffers[idx]);
			boost::interprocess::sharable_lock<upgradable_mutex_t> bufLock(pBuffer->mutex);
			int offset = pBuffer->lastMasked();
			if( offset>=0 ){

                if( pValue && reader ){
                    if(! reader->readRecord(pBuffer->data[offset],pValue) ){
                    	log().warnning(m_name.c_str(),this,__FUNCTION__,"read fail[idx:%d,offset:%d]",idx,offset);
						return CPos();
                    }
                }

                return CPos(idx,offset,m_info,m_buffers);
			}
		}

		return CPos();
    }

    /**
     * 获取下一个记录
     * @param pos
     * @return
     */
    CPos next( const CPos& pos,void* pValue=nullptr,CReader* reader=nullptr ){
    	SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);

    	boost::interprocess::sharable_lock<upgradable_mutex_t> sharebleInfoLock(pInfo->mutex);
		updateBuffers();

        if( !pos ){
        	log().info(m_name.c_str(),this,__FUNCTION__,"unvalide pos(%d,%d)",pos.getBufferIndex(),pos.getBufferOffset());
			return CPos();	// 位置无效
        }

        int offset = pos.getBufferOffset();
		for( int idx=pos.getBufferIndex();idx<pInfo->bufCount;++idx ){
			buffer_t* pBuffer = const_cast<buffer_t*>(m_buffers[idx]);
			boost::interprocess::sharable_lock<upgradable_mutex_t> sharableBufLock(pBuffer->mutex);
            offset = pBuffer->nextMasked(offset+1);

            if( offset>=0 ){
                if( pValue && reader ){
                    if( !reader->readRecord(pBuffer->data[offset], pValue) ){
                    	log().info(m_name.c_str(),this,__FUNCTION__,"read fail[buf:%d,offset:%d]",idx,offset);
                    	return CPos();
                    }
                }

                return CPos(idx,offset,m_info,m_buffers);
			}

			offset = -1;
		}

		return CPos();
    }

    CPos previous( const CPos& pos,void* pValue=nullptr,CReader* reader=nullptr ){
    	SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);

    	boost::interprocess::sharable_lock<upgradable_mutex_t> sharebleInfoLock(pInfo->mutex);
		updateBuffers();

        if( !pos ){
        	log().info(m_name.c_str(),this,__FUNCTION__,"unvalide pos(%d,%d)",pos.getBufferIndex(),pos.getBufferOffset());
			return CPos();	// 位置无效
        }

        int offset = pos.getBufferOffset();
		for( int idx = pos.getBufferIndex();idx>=0;--idx ){
			buffer_t* pBuffer = const_cast<buffer_t*>(m_buffers[idx]);
			boost::interprocess::sharable_lock<upgradable_mutex_t> sharableBufLock(pBuffer->mutex);
            offset = pBuffer->lastMasked(offset-1);

            if( offset>=0 ){
                if( pValue && reader ){
                    if( !reader->readRecord(pBuffer->data[offset], pValue) ){
                    	log().info(m_name.c_str(),this,__FUNCTION__,"read fail[buf:%d,offset:%d]",idx,offset);
                    	return CPos();
                    }
                }

                return CPos(idx,offset,m_info,m_buffers);
			}

			offset = buffer_t::SizeOfRecords;
		}

		return CPos();
    }

    /**
     * 获取位置
     * @param idx
     * @param offset
     * @return
     */
    CPos pos( TIndex bufIdx,TIndex bufOffset ){
    	SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);
    	boost::interprocess::sharable_lock<upgradable_mutex_t> sharebleInfoLock(pInfo->mutex);
    	try{
        	updateBuffers();

            if( bufIdx>=0 && bufIdx<pInfo->bufCount && bufOffset>=0 && bufOffset<buffer_t::SizeOfRecords){
                buffer_t* pBuffer = const_cast<buffer_t*>(m_buffers[bufIdx]);
    			boost::interprocess::sharable_lock<upgradable_mutex_t> sharableBufLock(pBuffer->mutex);

                if( bufOffset<pBuffer->count && pBuffer->isMasked(bufOffset) )
                    return CPos(bufIdx,bufOffset,&(m_info->magic),m_buffers[bufIdx]);
        	}

			return CPos();	// 无效的记录
    	}catch(...){
    		log().error(m_name.c_str(),this,__FUNCTION__,"系统异常");
    	}

    	return CPos();
    }

    inline CPos find( const TId& id,CFinder& finder ){
        CPos pos;
        find(id,finder,pos);
        return pos;
    }

    inline bool find( const TId& id,CFinder& finder,CPos& pos ){
        return find(&id,nullptr,nullptr,finder,&pos,nullptr,nullptr);
    }

    inline bool find( const TId& id,CFinder& finder,void* pValue,CReader& reader ){
        return find(&id,nullptr,nullptr,finder,nullptr,pValue,&reader);
    }

    inline bool find( const TId& id,CFinder& finder,CPos& pos,void* pValue,CReader& reader ){
        return find(&id,nullptr,nullptr,finder,&pos,pValue,&reader);
    }

    inline bool find( const char* name,CFinder& finder,CPos& pos ){
        return find(nullptr,name,nullptr,finder,&pos,nullptr,nullptr);
    }

    inline bool find( const char* name,CFinder& finder,void* pValue,CReader& reader ){
        return find(nullptr,name,nullptr,finder,nullptr,pValue,&reader);
    }

    inline bool find( const char* name,CFinder& finder,CPos& pos,void* pValue,CReader& reader ){
        return find(nullptr,name,nullptr,finder,&pos,pValue,&reader);
    }

    inline bool findByKey( void* key,CFinder& finder,CPos& pos ){
        return find(nullptr,nullptr,key,finder,&pos,nullptr,nullptr);
    }

    /**
     * 获取记录
     * @param pos
     * @param reader
     * @param value
     * @return
     */
    bool get( const CPos& pos,void* pValue,CReader& reader ){
    	SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);

    	boost::interprocess::sharable_lock<upgradable_mutex_t> sharebleLock(pInfo->mutex);
        updateBuffers();

        if( !pos ){
            log().warnning(m_name.c_str(),this,__FUNCTION__,"参数pos(%d,%d)无效",pos.getBufferIndex(),pos.getBufferOffset() );
            return false;
        }

        buffer_t* pBuffer = const_cast<buffer_t*>(m_buffers[pos.getBufferIndex()]);
        boost::interprocess::sharable_lock<upgradable_mutex_t> bufLock(pBuffer->mutex);

        if( pBuffer->isMasked(pos.getBufferOffset()) )
            return reader.readRecord(pBuffer->data[pos.getBufferOffset()], pValue);

    	return false;
    }

    /**
     * 设置数值
     * @param pos
     * @param writer
     * @param recorder
     * @return
     */
    inline bool set( CPos& pos,void* pValue,CWriter& writer){
        return set(nullptr,nullptr,nullptr,nullptr,&pos,pValue,writer);
    }

    inline bool set( const TId& id,CFinder& finder,void* pValue,CWriter& writer ){
        return set(&id,nullptr,nullptr,&finder,nullptr,pValue,writer);
    }

    inline bool set( const TId& id,CFinder& finder,CPos& pos,void* pValue,CWriter& writer ){
        return set(&id,nullptr,nullptr,&finder,&pos,pValue,writer);
    }

    inline bool set( const char* name,CFinder& finder,void* pValue,CWriter& writer ){
        return set(nullptr,name,nullptr,&finder,nullptr,pValue,writer);
    }

    inline bool set( const char* name,CFinder& finder,CPos& pos,void* pValue,CWriter& writer ){
        return set(nullptr,name,nullptr,&finder,&pos,pValue,writer);
    }

    inline bool setByKey( void* key,CFinder& finder,void* pValue,CWriter& writer ){
        return set(nullptr,nullptr,key,&finder,nullptr,pValue,writer);
    }

    inline bool setByKey( void* key,CFinder& finder,CPos& pos,void* pValue,CWriter& writer ){
        return set(nullptr,nullptr,key,&finder,&pos,pValue,writer);
    }

    inline bool update( CPos& pos,void* pValue,CUpdater& updater ){
        return update(nullptr,nullptr,nullptr,nullptr,&pos,pValue,updater);
    }

    inline bool update( const TId& id,CFinder& finder,void* pValue,CUpdater& updater ){
        return update(&id,nullptr,nullptr,&finder,nullptr,pValue,updater);
    }

    inline bool update( const TId& id,CFinder& finder,CPos& pos,void* pValue,CUpdater& updater ){
        return update(&id,nullptr,nullptr,&finder,&pos,pValue,updater);
    }

    inline bool update( const char* name,CFinder& finder,void* pValue,CUpdater& updater ){
        return update(nullptr,name,nullptr,&finder,nullptr,pValue,updater);
    }

    inline bool update( const char* name,CFinder& finder,CPos& pos,void* pValue,CUpdater& updater ){
        return update(nullptr,name,nullptr,&finder,&pos,pValue,updater);
    }

    inline bool updateByKey( void* key,CFinder& finder,void* pValue,CUpdater& updater ){
        return update(nullptr,nullptr,key,&finder,nullptr,pValue,updater);
    }

    inline bool updateByKey( void* key,CFinder& finder,CPos& pos,void* pValue,CUpdater& updater ){
        return update(nullptr,nullptr,key,&finder,&pos,pValue,updater);
    }

    /**
     * 移除共享记录
     */
    void remove( CUnloader& unloader ){
    	SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);

    	boost::interprocess::scoped_lock<upgradable_mutex_t> lock(pInfo->mutex);
    	updateBuffers();

    	try{
    		for( int bufferIndex=m_buffers.size()-1;bufferIndex>=0;--bufferIndex ){
    			buffer_t* pBuffer = const_cast<buffer_t*>(m_buffers[bufferIndex]);
    			boost::interprocess::scoped_lock<upgradable_mutex_t> bufLock(pBuffer->mutex);

    			for( int offset=pBuffer->SizeOfRecords-1;offset>=0;--offset ){
    				if( pBuffer->isMasked(offset) ){
    					if( !unloader.unloadRecord(pBuffer->data[offset]) ){
    						log().warnning(m_name.c_str(),this,__FUNCTION__,"卸载记录(%d:%d)失败",bufferIndex,offset);
    					}
    				}
    			}

    			unloadBuffer(bufferIndex);
    		}

        	m_magic->destroy();
        	boost::interprocess::shared_memory_object::remove(m_name.c_str());
    	}catch(...){
    		log().error(m_name.c_str(),this,__FUNCTION__,"系统异常");
    	}
    }

    /**
     * 加载一个最新的记录
     * @param loader
     * @param pValue
     * @param reader
     * @return
     */
    CPos loadNew( CLoader& loader,void* pValue=nullptr,CReader* reader=nullptr ){
    	SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);
        boost::interprocess::upgradable_lock<upgradable_mutex_t> upgradableInfoLock(pInfo->mutex);
        updateBuffers();

    	try{
    		if( !filterLoader(loader) ){
    			log().debug(m_name.c_str(),this,__FUNCTION__,"filter loader fail");
    			return CPos();
    		}

    		if( !loader.next() ){
    			log().debug(m_name.c_str(),this,__FUNCTION__,"no new record");
    			return CPos();
    		}

    		int bufIdx = 0;
    		int bufOffset = 0;
    		buffer_t* pBuffer;
            if( !loadNewRecord(upgradableInfoLock, pInfo, loader, bufIdx, bufOffset, pBuffer) ){
            	log().warnning(m_name.c_str(),this,__FUNCTION__,"load new record fail");
            	return CPos();
            }

            if( pValue && reader ){
            	if( !reader->readRecord(pBuffer->data[bufOffset], pValue) ){
            		log().warnning(m_name.c_str(),this,__FUNCTION__,"read record faile[%d,%d]",bufIdx,bufOffset);
					return CPos();
            	}
            }

            return CPos(bufIdx,bufOffset,m_info,m_buffers);
    	}catch(...){
    		log().error(m_name.c_str(),this,__FUNCTION__,"系统异常");
    		return false;
    	}
    }

    bool loadNews( CLoader& loader ){
    	SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);
        boost::interprocess::upgradable_lock<upgradable_mutex_t> upgradableInfoLock(pInfo->mutex);
        updateBuffers();

    	try{
    		if( !filterLoader(loader) ){
    			log().debug(m_name.c_str(),this,__FUNCTION__,"filter loader fail");
    			return false;
    		}

    		int bufIdx = 0;
    		int bufOffset = 0;
    		buffer_t* pBuffer;

    		while( loader.next() ){
                if( !loadNewRecord(upgradableInfoLock, pInfo, loader, bufIdx, bufOffset, pBuffer) ){
                	log().warnning(m_name.c_str(),this,__FUNCTION__,"load new record fail");
                	return false;
                }
    		}

    		return true;
    	}catch(...){
    		log().error(m_name.c_str(),this,__FUNCTION__,"系统异常");
    		return false;
    	}
    }

    /**
     * 重新加载记录
     * @param pos
     * @param reloader
     * @return
     */
    inline bool reload( CPos& pos,CLoader& loader ){
        return reload(pos,loader,nullptr,nullptr);
    }

    inline bool reload( CPos& pos,CLoader& loader,void* pValue,CReader& reader ){
        return reload(pos,loader,pValue,&reader);
    }

    bool reload( const CPos& pos,CLoader& loader,void* pValue,CReader* reader){
        SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);

        boost::interprocess::sharable_lock<upgradable_mutex_t> sharableInfoLock(pInfo->mutex);
        try{
            updateBuffers();

            if( !pos ){
                log().warnning(m_name.c_str(),this,__FUNCTION__,"参数pos(%d,%d)无效",pos.getBufferIndex(),pos.getBufferOffset() );
                return false;
            }

            buffer_t* pBuffer = const_cast<buffer_t*>(m_buffers[pos.getBufferIndex()]);
            boost::interprocess::sharable_lock<upgradable_mutex_t> sharableBufLock(pBuffer->mutex);
            if( loader.reloadRecord(pBuffer->data[pos.getBufferOffset()]) ){
                if( pValue && reader )
                    return reader->readRecord(pBuffer->data[pos.getBufferOffset()],pValue);
                else
                    return true;
            }else
                return false;
        }catch(...){
            log().error(m_name.c_str(),this,__FUNCTION__,"系统异常");
        }

        return false;
    }

    bool reload( const TId* id,const char* name,void* key,CFinder& finder,CLoader& loader,CPos* pos,void* pValue,CReader* reader ){
        SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);

        boost::interprocess::sharable_lock<upgradable_mutex_t> sharableInfoLock(pInfo->mutex);
        try{
            updateBuffers();

            buffer_t* pBuffer = nullptr;
            int bufIdx = 0;
            int bufOffset = 0;

            pBuffer = find(pInfo,id,name,key,finder,bufIdx,bufOffset,pValue,reader,nullptr,nullptr,&loader,nullptr);

            if( pBuffer ){
                if( pos )
                    pos->set(bufIdx,bufOffset,m_info,m_buffers);

                return true;
            }else
                return false;
        }catch(...){
            log().error(m_name.c_str(),this,__FUNCTION__,"系统异常");
        }

        return false;
    }

    bool unload( const CPos& pos,CUnloader& unloader ){
    	SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);
        boost::interprocess::upgradable_lock<upgradable_mutex_t> upgradableInfoLock(pInfo->mutex);
    	try{
    		updateBuffers();
        	if( !isValid(pos) ){
        		log().warnning(m_name.c_str(),this,__FUNCTION__,"参数pos(%d,%d)无效",pos.getBufferIndex(),pos.getBufferOffset() );
        		return false;
        	}

			buffer_t* pBuffer = const_cast<buffer_t*>(m_buffers[pos.getBufferIndex()]);
            boost::interprocess::upgradable_lock<upgradable_mutex_t> upgradableBufLock(pBuffer->mutex);
            if( pBuffer->isMasked(pos.getBufferOffset()) ){
                boost::interprocess::scoped_lock<upgradable_mutex_t> scopedBufLock(boost::move(upgradableBufLock));
                if( unloader.unloadRecord(pBuffer->data[pos.getBufferOffset()]) ){
                    pBuffer->unmask(pos.getBufferOffset());
                    --pBuffer->count;

                    boost::interprocess::scoped_lock<upgradable_mutex_t> scopdInfoLock(boost::move(upgradableInfoLock));
                    --pInfo->recordCount;

                    return true;
                }
            }
    	}catch(...){
    		log().error(m_name.c_str(),this,__FUNCTION__,"系统异常");
    	}

    	return false;
    }

    inline bool unload(const TId& id,CFinder& finder,CUnloader& unloader ){
        return unload(&id,nullptr,nullptr,finder,unloader);
    }

    inline bool unload( const char* name,CFinder& finder,CUnloader& unloader ){
        return unload(nullptr,name,nullptr,finder,unloader);
    }

    inline bool unloadByKey( void* key,CFinder& finder,CUnloader& unloader ){
        return unload(nullptr,nullptr,key,finder,unloader);
    }

    bool unload( const TId* id,const char* name,void* key,CFinder& finder,CUnloader& unloader ){
        SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);
        boost::interprocess::upgradable_lock<upgradable_mutex_t> upgradableLock(pInfo->mutex);
        try{
            updateBuffers();
            int bufIdx = 0;
            int bufOffset = 0;

            buffer_t* pBuffer = find(pInfo,id,name,key,finder,bufIdx,bufOffset,nullptr,nullptr,nullptr,nullptr,nullptr,&unloader);
            if( pBuffer ){
                // 卸载完成
                boost::interprocess::scoped_lock<upgradable_mutex_t> scopedInfoLock(boost::move(upgradableLock));

                // 设置缓冲区释放标致
                pBuffer->unmask(bufOffset);
                --pBuffer->count;

                // 全局区
                --pInfo->recordCount;

                m_magic->refresh();

                return true;
            }
        }catch(...){
            log().error(m_name.c_str(),this,__FUNCTION__,"系统异常");
        }

        return false;
    }
protected:
    bool find( const TId* id,const char* name,void* key,CFinder& finder,CPos* pos,void* pValue,CReader* reader ){
        SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);
        boost::interprocess::sharable_lock<upgradable_mutex_t> sharableInfoLock(pInfo->mutex);

        updateBuffers();
        buffer_t* pBuffer = nullptr;
        int bufIdx = 0;
        int bufOffset = 0;

        pBuffer = find(pInfo,id,name,key,finder,bufIdx,bufOffset,pValue,reader,nullptr,nullptr,nullptr,nullptr);

        if( pBuffer ){
            if( pos )
                pos->set(bufIdx,bufOffset,m_info,m_buffers);
            return true;
        }else
            return false;
    }

    buffer_t* find( const SBufferInfo* pInfo, const TId* id,const char* name,void* key,CFinder& finder,int& bufIdx,int& bufOffset,void* pValue,CReader* reader,CWriter* writer,CUpdater* updater,CLoader* reloader,CUnloader* unloader ){
        for(;bufIdx<pInfo->bufCount;++bufIdx){
            buffer_t* pBuffer = const_cast<buffer_t*>(m_buffers[bufIdx]);
            if( unloader ){ // 卸载操作
                boost::interprocess::upgradable_lock<upgradable_mutex_t> upgradableBufLock(pBuffer->mutex);
                if( !pBuffer->isEmpty() ){
                    for(;bufOffset<buffer_t::SizeOfRecords;++bufOffset ){
                        if( pBuffer->isMasked(bufOffset) ){
                            if( (id && finder.compareId(pBuffer->data[bufOffset],*id))||
                                    (name && finder.compareName(pBuffer->data[bufOffset],name))||
                                    (key && finder.compareAny(pBuffer->data[bufOffset],key))){
                                // 找到节点
                                boost::interprocess::scoped_lock<upgradable_mutex_t> scopedBufLock(boost::move(upgradableBufLock));
                                if( !unloader->unloadRecord(pBuffer->data[bufOffset]) ){
                                    log().warnning(m_name.c_str(),this,__FUNCTION__,"卸载记录(%d,%d)失败",bufIdx,bufOffset);
                                    return nullptr;
                                }

                                pBuffer->unmask(bufOffset);
                                --pBuffer->count;   // 数量减少
                                log().debug(m_name.c_str(),this,__FUNCTION__,"卸载记录(%d,%d)成功",bufIdx,bufOffset);
                                return pBuffer;
                            }
                        }
                    }
                }
                bufOffset = 0;
            }else{
                boost::interprocess::sharable_lock<upgradable_mutex_t> sharableBufLock(pBuffer->mutex);
                if( !pBuffer->isEmpty() ){
                    for(;bufOffset<buffer_t::SizeOfRecords;++bufOffset ){
                        if( pBuffer->isMasked(bufOffset) ){
                            if( (id && finder.compareId(pBuffer->data[bufOffset],*id))||
                                    (name && finder.compareName(pBuffer->data[bufOffset],name))||
                                    (key && finder.compareAny(pBuffer->data[bufOffset],key))){
                                // 找到节点
                                if( reloader ){
                                    if( !reloader->reloadRecord(pBuffer->data[bufOffset]) ){
                                        log().warnning(m_name.c_str(),this,__FUNCTION__,"重新加载记录(%d,%d)失败",bufIdx,bufOffset);
                                        return nullptr;
                                    }else{
                                        log().debug(m_name.c_str(),this,__FUNCTION__,"重新加载记录(%d,%d)成功",bufIdx,bufOffset);
                                    }
                                }
                                if( writer&& pValue ){
                                    if( !writer->writeRecord(pValue,pBuffer->data[bufOffset]) ){
                                        log().warnning(m_name.c_str(),this,__FUNCTION__,"写入记录(%d,%d)失败",bufIdx,bufOffset);
                                        return nullptr;
                                    }
                                    // 频繁操作，不日志
                                }
                                if( updater && pValue ){
                                    if( !updater->updateRecord(pValue,pBuffer->data[bufOffset]) ){
                                        log().warnning(m_name.c_str(),this,__FUNCTION__,"卸载记录(%d,%d)失败",bufIdx,bufOffset);
                                        return nullptr;
                                    }
                                    // 频繁操作，不日志
                                }

                                if( reader && pValue ){
                                    if( !reader->readRecord(pBuffer->data[bufOffset],pValue) ){
                                        log().warnning(m_name.c_str(),this,__FUNCTION__,"读取记录(%d,%d)失败",bufIdx,bufOffset);
                                        return nullptr;
                                    }
                                    // 频繁操作，不日志
                                }

                                return pBuffer;
                            }
                        }
                    }
                }
                bufOffset = 0;
            }
        }

        return nullptr;
    }

    bool set( const TId* id,const char* name,void* key,CFinder* finder,CPos* pos,void* pValue,CWriter& writer){
        SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);
        boost::interprocess::sharable_lock<upgradable_mutex_t> sharableInfoLock(pInfo->mutex);
        try{
            updateBuffers();
            if( finder ){
                int bufIdx = 0;
                int bufOffset = 0;
                buffer_t* pBuffer = find(pInfo,id,name,key,finder,bufIdx,bufOffset,pValue,nullptr,&writer,nullptr,nullptr,nullptr);
                if( pBuffer ){
                    if( pos )
                        pos->set(bufIdx,bufOffset,m_info,m_buffers[bufIdx]);
                    return true;
                }else
                    return false;
            }else{
                if( !isValid(*pos) ){
                    log().warnning(m_name.c_str(),this,__FUNCTION__,"参数pos(%d,%d)无效",pos->getBufferIndex(),pos->getBufferOffset() );
                    return false;
                }

                buffer_t* pBuffer = const_cast<buffer_t*>(m_buffers[pos->getBufferIndex()]);
                boost::interprocess::sharable_lock<upgradable_mutex_t> sharableBufLock(pBuffer->mutex);	// 虽然是写操作，但是写的是数据，不是缓冲区信息，所以使用读

                if( pBuffer->isMasked(pos->getBufferOffset()) )
                    return writer.writeRecord(pValue,pBuffer->data[pos->getBufferOffset()]);
            }
        }catch(...){
            log().error(m_name.c_str(),this,__FUNCTION__,"系统异常");
        }

        return false;
    }

    bool update( const TId* id,const char* name,void* key,CFinder* finder,CPos* pos,void* pValue,CUpdater& updater ){
        SBufferInfo* pInfo = const_cast<SBufferInfo*>(m_info);
        boost::interprocess::sharable_lock<upgradable_mutex_t> sharableInfoLock(pInfo->mutex);
        try{
            updateBuffers();
            if( finder ){
                int bufIdx = 0;
                int bufOffset = 0;
                buffer_t* pBuffer = find(pInfo,id,name,key,*finder,bufIdx,bufOffset,pValue,nullptr,nullptr,&updater,nullptr,nullptr);
                if( pBuffer ){
                    if( pos )
                        pos->set(bufIdx,bufOffset,m_info,m_buffers);
                    return true;
                }else
                    return false;
            }else{
                if( !isValid(*pos) ){
                    log().warnning(m_name.c_str(),this,__FUNCTION__,"参数pos(%d,%d)无效",pos->getBufferIndex(),pos->getBufferOffset() );
                    return false;
                }

                buffer_t* pBuffer = const_cast<buffer_t*>(m_buffers[pos->getBufferIndex()]);
                boost::interprocess::sharable_lock<upgradable_mutex_t> sharableBufLock(pBuffer->mutex);
                if( pBuffer->isMasked(pos->getBufferOffset()) )
                    return updater.updateRecord(pValue,pBuffer->data[pos->getBufferOffset()]);
            }
        }catch(...){
            log().error(m_name.c_str(),this,__FUNCTION__,"系统异常");
        }

        return false;
    }

private:
    /**
     * 加载缓冲区
     * @param index
     * @return
     */
    boost::interprocess::mapped_region* loadBuffer( TIndex index,volatile buffer_t* & vptr )const{
    	char name[SizeOfName+6];
    	nameOfBuffer(name, index);
    	return getSharedMemory<buffer_t>(name, CUnrestrictedPermissions(),&vptr);
    }

    void unloadBuffer( TIndex index )const{
    	char name[SizeOfName+6];
    	nameOfBuffer(name, index);
    	boost::interprocess::shared_memory_object::remove(name);
    }

    /**
     * 更新缓冲区指针
     * @return
     */
    bool updateBuffers(){
    	if( m_magic->update() ){
    		log().info(m_name.c_str(),this,__FUNCTION__,"全局魔数变化，加载新增缓冲区(%d->%d)",m_buffers.size(),m_info->bufCount);

    		for( TIndex index=m_buffers.size();index<m_info->bufCount;++index ){
    			volatile buffer_t* vptr;
    			m_buffersMappedRegion.append(loadBuffer(index, vptr));
    			m_buffers.push_back(vptr);
    		}

    		return true;
    	}

    	return false;
    }

    /**
     * 测试pos是否有效
     * @param pos
     * @return
     */
    inline bool isValid( const CPos& pos )const{
        return pos.isValid() && pos.getBufferIndex()<m_buffers.size() && pos.getBufferOffset()<buffer_t::SizeOfRecords;
    }

    bool filterLoader( CLoader& loader ){
		// 过滤已经添加过的
		for( int idx=0;idx<m_buffers.size();++idx ){
			buffer_t* pBuffer = const_cast<buffer_t*>(m_buffers[idx]);
			boost::interprocess::sharable_lock<upgradable_mutex_t> sharableBufLock(pBuffer->mutex);
			int offset = pBuffer->nextMasked();
			while( offset>=0 ){
				if( !loader.addALoaded(pBuffer->data[offset]) ){
					log().warnning(m_name.c_str(),this,__FUNCTION__,"add a loaded fail[idx:%d,offset:%d]",idx,offset);
					return false;
				}
				offset = pBuffer->nextMasked(offset+1);
			}
		}

		if( !loader.filterLoaded() ){
			log().warnning(m_name.c_str(),this,__FUNCTION__,"filter loaded fail");
			return false;
		}

		return true;
    }

    /**
     * 查找新的空闲记录区，并加载新的记录。
     * bufIdx,bufOffset标记开始查找的范围。之前的不再查找
     * @param upgradableInfoLock
     * @param pInfo
     * @param loader
     * @param bufIdx
     * @param bufOffset
     * @param pBuffer
     * @return
     */
    bool loadNewRecord(boost::interprocess::upgradable_lock<upgradable_mutex_t>& upgradableInfoLock,SBufferInfo* pInfo,CLoader& loader,int& bufIdx,int& bufOffset,buffer_t* &pBuffer){
        // 在已有的缓冲区中查找空闲位置
    	for( ;bufIdx<m_buffers.size();++bufIdx ){
            pBuffer = const_cast<buffer_t*>(m_buffers[bufIdx]);
            boost::interprocess::upgradable_lock<upgradable_mutex_t> upgradableBufLock(pBuffer->mutex);
            if( !pBuffer->isFull() ){
                boost::interprocess::scoped_lock<upgradable_mutex_t> scopBufLock(boost::move(upgradableBufLock));
                bufOffset = pBuffer->firstUnmasked();
                if( !loader.loadRecord(pBuffer->data[bufOffset]) ){
                    log().warnning(m_name.c_str(),this,__FUNCTION__,"load record fail(%d,%d)",bufIdx,bufOffset);
                    return false;
                }

                pBuffer->mask(bufOffset);
                ++pBuffer->count;

                boost::interprocess::scoped_lock<upgradable_mutex_t> scopInfoLock(boost::move(upgradableInfoLock));
                ++pInfo->recordCount;

                log().debug(m_name.c_str(),this,__FUNCTION__,"load new record(%d,%d)buf:%d,total:%d",bufIdx,bufOffset,pBuffer->count,pInfo->recordCount);
                return true;
            }
    	}

        // 创建新的缓冲区
        boost::interprocess::scoped_lock<upgradable_mutex_t> scopInfoLock(boost::move(upgradableInfoLock));
        pBuffer = loadNewBuffer(pInfo);

        if( !loader.loadRecord(pBuffer->data[0]) ){
            log().warnning(m_name.c_str(),this,__FUNCTION__,"load record fail(%d,%d)",pInfo->recordCount,0);
            return false;
        }

        pBuffer->mask(0);
        pBuffer->count = 1;
        ++pInfo->recordCount;

        bufIdx = pInfo->bufCount-1;
        bufOffset = 0;

        log().debug(m_name.c_str(),this,__FUNCTION__,"load new record(%d,%d)buf:%d,total:%d",bufIdx,bufOffset,pBuffer->count,pInfo->recordCount);

        return true;
    }

    /**
     * 查找下一个空闲的记录
     * @param bufferIndex 当前记录索引
     * @param bufferOffset 当前记录偏移,第一个位置需要设置为-1
     * @return 查找到了记录指针
     */
    buffer_t* nextUnmasked( const SBufferInfo* pInfo,TIndex& bufferIndex,TIndex& bufferOffset ){
    	while( bufferIndex<pInfo->bufCount ){
    		++bufferOffset;
        	if( bufferOffset>=buffer_t::size() ){
        		++bufferIndex;
        		bufferOffset = -1;
        	}else{
            	buffer_t* pBuffer = const_cast<buffer_t*>(m_buffers[bufferIndex]);
            	if( !pBuffer->ifMasked(bufferOffset) )
            		return pBuffer;
        	}
    	}

    	return nullptr;
    }

    /**
     * 追加新的缓冲区
     * @param pInfo
     * @return
     */
    buffer_t* loadNewBuffer( SBufferInfo* pInfo ){
    	volatile buffer_t* vptr;
    	mapped_region_t* region = loadBuffer(pInfo->bufCount, vptr);

    	buffer_t* pBuffer = const_cast<buffer_t*>(vptr);
    	pBuffer->init();

    	m_buffers.push_back(vptr);
    	m_buffersMappedRegion.append(region);
    	m_magic->refresh();

    	log().info(m_name.c_str(),this,__FUNCTION__,"加载缓冲区%d",pInfo->bufCount);

    	++ pInfo->bufCount;

    	return pBuffer;
    }

    /**
     * 设置加载器
     * @param pId
     * @param name
     * @param key
     * @param loader
     * @return
     */
    inline bool setLoader( const TId* pId,const char* name,void* key,CLoader& loader ){
    	if( pId ){
    		if( !loader.setId(*pId) ){
    			log().info(m_name.c_str(),this,__FUNCTION__,"设置加载器失败(id:%d)",*pId);
    			return false;
    		}
    	}else if( name ){
    		if( !loader.setName(name) ){
    			log().info(m_name.c_str(),this,__FUNCTION__,"设置加载器失败(name:%s)",name);
    			return false;
    		}
    	}else if( key ){
    		if( !loader.setKey(key) ){
    			log().info(m_name.c_str(),this,__FUNCTION__,"设置加载器失败(key:%ld)",key);
    			return false;
    		}
    	}else{
    		log().info(m_name.c_str(),this,__FUNCTION__,"未指定有效参数");
    		return false;
    	}

    	return true;
    }
protected:
    /**
     * 获取缓冲区名
     * @param name
     * @param index
     */
    inline void nameOfBuffer(char* name,TIndex index)const{
    	std::sprintf(name,"%s-%05d",m_name,index);
    }

private:
    TScopedPtr<CMagic> m_magic;	               //!< 全局魔数,代表缓冲区个数有变化

    volatile SBufferInfo* m_info;	           //!< 全局信息指针
    dm::TScopedPtr<mapped_region_t> m_infoMappedRegion;

    std::vector<volatile buffer_t*> m_buffers; //!< 缓冲区列表
    dm::TCPtrVector<mapped_region_t> m_buffersMappedRegion;

    name_t m_name;	//!< 缓冲区名字
};

}
}
#endif
